function Add-WorkSpace {
<#
.SYNOPSIS
Creates a TFS workspace based on the mappings provided.

.DESCRIPTION
This function is helpful when you hava a set of mappings in one workspace that you want to copy to either another location on disk, another machine or you want to change the server branch the the mappings are bound to.

.PARAMETER Mappings
List of mappings to include in workspace. These can be piped from an existing workspace and you can use the BranchToken and LocalPathToken to replace new server and local path values to be used for this workspace.

.PARAMETER TfsUrl
The TFS Collection URL to use for connecting to TFS

.PARAMETER LocalSourcePath
Local path where the workspace mappings should be rooted to

.PARAMETER Branch
Server path from which to root mappings

.PARAMETER BranchToken
String in the server path of the Mappings to be replaced with the Branch parameter

.PARAMETER LocalPathToken
String in the local path of the Mappings to be replaced with the LocalSourcePath parameter. The default is 'c:\'.

.PARAMETER Force
If a wokspace already exists that was not created by BigGit then add these mappings to that workspace


.EXAMPLE
Invoke-TF workfold /workspace:"SomeOtherWorkspace;Matt Wrock" | Add-workspace -tfsUrl http://myserver:8080/tfs -localSourcePath "c:\dev\src\" -localPathToken "c:\" -Branch $/my/branch -BranchToken $/original/branch

This will create a new workspace based on the mappings of SomeOtherWorkspace and replace server path mappings starting with $/original/branch with $/my/branch and replace local path mappings starting with c:\ with c:\dev\src\

.EXAMPLE
Invoke-TF workfold /workspace:"SomeOtherWorkspace;Matt Wrock" | Add-workspace -tfsUrl http://myserver:8080/tfs -localSourcePath "c:\dev\src\" -localPathToken "c:\"

This will create a new workspace based on the mappings of SomeOtherWorkspace and replace local path mappings starting with c:\ with c:\dev\src\. The server paths will be copied from the original mappings.

.EXAMPLE
Add-workspace -mappings " $/my/branch/folder1: c:\dev\src\folder1"," $/my/branch/folder2: c:\dev\src\folder2" -tfsUrl http://myserver:8080/tfs -localSourcePath "c:\dev\src\"

This will create a new workspace and use the mappings passed in as is since no token parameters were used.

.NOTES
While this function may provide some value for use outside of typical Git-Ennlistment intentions, you should always use Add-VolitileEnlistment, Add-VolitileEnlistment and Add-PartialBranch to create your workspaces involved with BigGit RIs and FIs. These wrap this function and track the workspaces so that integrations back and forth between git and TFS will work.

.LINK
https://BigGit.Codeplex.com
Add-PartialBranch
Add-VolitileEnlistment
Add-NonVolatileEnlistment
#>        
    param(
        [Parameter(position=0,Mandatory=$True,ValueFromPipeline=$True)]
        [string[]] $mappings,
        [Parameter(Mandatory=$true)]
        [string] $tfsUrl, 
        [Parameter(Mandatory=$true)]
        [string] $localSourcePath, 
        [string] $branch = $null, 
        [string] $branchToken = '$/server/path/to/branch/', 
        [string] $localPathToken = 'c:\',
        [switch] $force
    )
    begin {
        $currentDirectory = resolve-path .
        if(Test-workspace $localSourcePath) {
            if(!$force) {
                Write-BigGitMessage "Use the -force argument to overwrite mappings"
                $returnFalse = $true
                return
            } else {
                $workspaceExists = $true
            }
        }
        try {
            if($branch -and !$branch.EndsWith("/")) {$branch += "/"}
            $branchToken = $branchToken.ToLower()
            $localPathToken = $localPathToken.ToLower()
            if(!$branchToken.EndsWith("/")) {$branchToken += "/"}
            if(!$localPathToken.EndsWith("\")) {$localPathToken += "\"}            
            $src = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($localSourcePath)
            if(!(Test-Path $src)) {mkdir $src | out-null }
            Set-Location $src
            Invoke-TF workspaces /s:$tfsUrl
            $workspaceName = Get-WorkspaceName $src
            if(!$workspaceExists) {
                if($branch){
                    try {Invoke-TF dir $branch /collection:$tfsUrl | out-null } catch { throw "The branch specified $branch could not be found on the server $tfsUrl." }
                }
                Write-BigGitMessage "Creating workspace $workspaceName at $src"
                Invoke-TF workspace /new /noprompt $workspaceName /collection:$TfsUrl /location:local
            }
            try {Invoke-TF workfold /unmap '$/' /workspace:$workspaceName /collection:$TfsUrl | out-null } catch {}
        } catch{return $false} finally {Set-Location $currentDirectory}
    }
    process {
        if($returnFalse) {return}
        try {
            Set-Location $src
            foreach($map in $mappings){
                if($map.startsWith(" $")){
                    $mapParts = -Split $map
                    $mappingsource = $mapParts[0].Replace(":","")
                    $mappingsource = $mappingsource.ToLower().Replace($branchToken, $branch)
                    $newMap = $mapParts[1].ToLower().replace("$localPathToken","$src\")
                    if("$newMap\" -eq $localPathToken) {$newMap = "$src"}
                    Write-BigGitMessage "Mapping $mappingsource to $newMap"
                    Invoke-TF workfold $mappingsource $newMap /workspace:$workspaceName /collection:$TfsUrl
                }
                elseif ($map.startsWith(" (cloaked)")) {
                    $mapParts = -Split $map
                    $mappingsource = $mapParts[1].ToLower().Replace(":","")
                    $mappingsource = $mappingsource.ToLower().Replace($branchToken, $branch)
                    Write-BigGitMessage "Cloaking $mappingsource"
                    Invoke-TF workfold /cloak $mappingsource /workspace:$workspaceName /collection:$TfsUrl
                }
            }
        } catch{return $false} finally {Set-Location $currentDirectory}
    }
    end {
        try {
            if($returnFalse) {return $false}
            Set-Location $src
            Write-BigGitMessage "Getting Latest Source"
            Invoke-TF get
        } finally {Set-Location $currentDirectory}
        return $true
    }
}